package com.rd.sys.action.analysis;

import com.rd.sys.action.BaseAction;
import com.rd.sys.common.AutoImageNote;
import com.rd.sys.common.AutoSaveData;
import com.rd.sys.common.base.CommonConstants;
import com.rd.sys.common.fileexport.ExportFile;
import com.rd.sys.common.utils.JacksonMapper;
import com.rd.sys.common.utils.cache.AnalysisCache;
import com.rd.sys.common.utils.client.AnalysisPathUtils;
import com.rd.sys.common.utils.crypto.BASE64;
import com.rd.sys.dto.analysis.statistic.StatisticExportDto;
import com.rd.sys.dto.client.store.Result;
import com.rd.sys.dto.commmon.enums.ExportEnum;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * @author admin
 * Created time 2019/12/30 16:13
 */
public class AutoSaveAction extends BaseAction {

    private String projectCode;
    private String schemeCode;
    private String materialCode;
    private String materialSuffix;

    public void clear() throws IOException {
        clearBrowserCache();
        response.setStatus(200);
        response.getWriter().write("ok");
    }

    public void save() throws Exception {
        clearBrowserCache();
        Map<String, String> reMap = new HashMap<String, String>();
        try {

            StringBuilder builder = new StringBuilder();

            InputStream is = request.getInputStream();
            byte[] b = new byte[4096];
            for (int n; (n = is.read(b)) != -1; ) {
                builder.append(new String(b, 0, n));
            }
            if (builder.length() < 1) {
                toSave();
                return;
            }
            String data = URLDecoder.decode(builder.toString(), "utf-8");
            data = data.substring(5);
            autoSave(data);

            response.setContentType("application/json");
            response.setStatus(200);
            reMap.put("result", "success");
            response.getWriter().write(JacksonMapper.bean2Json(reMap));
        } catch (Exception e) {
            e.printStackTrace();
            reMap.put("result", "failed");
            response.setContentType("application/json");
            response.setStatus(500);
            response.getWriter().write(JacksonMapper.bean2Json(reMap));
        }

    }

    public void report() throws Exception{
        Map map = request.getParameterMap ();
        System.out.println ();
    }

    private void autoSave(String data) throws UnsupportedEncodingException, ExecutionException {
        AutoSaveData autoSaveData = (AutoSaveData) JacksonMapper.json2Bean(data, AutoSaveData.class);


        String userCode = autoSaveData.getUserCode();
        String projectCode = autoSaveData.getProjectCode();
        String schemeCode = autoSaveData.getSchemeCode();
        String materialCode = autoSaveData.getMaterialCode();
        String materialType = autoSaveData.getMaterialType();
        String key = userCode + CommonConstants.AnalysisConstats.CACHE_SPLIT + projectCode
                + CommonConstants.AnalysisConstats.CACHE_SPLIT + schemeCode;
        String resultCode = readResultCode(key, autoSaveData.getCheckBoxName());
        // 生成文件路径
        String basePath = AnalysisPathUtils.findSchemePath(userCode, projectCode, schemeCode) + resultCode + CommonConstants.SysParamConstants.FILE_SEPARATOR;
        String path = basePath + "data" + CommonConstants.SysParamConstants.FILE_SEPARATOR;
        File outFile = new File(path);
        if (!outFile.exists()) {
            if (!outFile.mkdirs()) {
                throw new RuntimeException("不能创建文件目录");
            }
        }
        System.out.println(path);
        for (AutoImageNote note : autoSaveData.getImages()) {
            if (note.getAnalysisType().equalsIgnoreCase("heatmap")) {
                saveImage(URLDecoder.decode(note.getBase(), "utf-8"), path + materialCode + "_heatMap.jpg");
            }
            if (note.getAnalysisType().equalsIgnoreCase("routeMap")) {
                saveImage(URLDecoder.decode(note.getBase(), "utf-8"), path + materialCode + "_routeMap.jpg");
            }
            if (note.getAnalysisType().equalsIgnoreCase("focusMap")) {
                saveImage(URLDecoder.decode(note.getBase(), "utf-8"), path + materialCode + "_focusMap.jpg");
            }
            if (note.getAnalysisType().equalsIgnoreCase("gridMap")) {
                saveImage(URLDecoder.decode(note.getBase(), "utf-8"), path + materialCode + "_gridMap.jpg");
            }
            if (note.getAnalysisType().equalsIgnoreCase("interestArea")) {
                saveImage(URLDecoder.decode(note.getBase(), "utf-8"), path + materialCode + "_interestArea.jpg");
            }
        }

        // 保存报表
        StatisticExportDto exportDto = new StatisticExportDto(autoSaveData.getUserCode(), projectCode,
                schemeCode, resultCode, materialCode);
        // 保存注视点
        ExportEnum.Type type = ExportEnum.Type.StatFixationData;
        File f1 = new File(path + materialCode + "_StatFixation.csv");
        ExportFile.preProcess(type.getCode(), f1);
        ExportFile.process(type.getCode(), f1, exportDto);

        // 保存扫视点
//        type = ExportEnum.Type.StatSaccadeData;
//        File f2 = new File(path+materialCode+"_StatSaccade.csv");
//        ExportFile.preProcess(type.getCode(),f2);
//        ExportFile.process(type.getCode(),f2,exportDto);


        // 保存
        type = ExportEnum.Type.StatPupilData;
        File f3 = new File(path + materialCode + "_StatPupil.csv");
        ExportFile.preProcess(type.getCode(), f3);
        ExportFile.process(type.getCode(), f3, exportDto);
        // 保存结果
        List<Result> listResult = AnalysisCache.ResultCache.get(key);
        saveResultData(resultCode, userCode, projectCode, schemeCode, materialCode, path);

    }

    private void saveResultData(String resultCode, String userCode, String projectCode, String schemeCode, String materialCode, String path) {
        ExportEnum.Type type = ExportEnum.Type.ResultRawData;
//        for (Result result : listResult){
        File f4 = new File(path + resultCode + "_StatResult.csv");
        if (!f4.exists()) {
            StatisticExportDto exportDto1 = new StatisticExportDto(userCode, projectCode,
                    schemeCode, resultCode, materialCode);
            ExportFile.preProcess(type.getCode(), f4);
            ExportFile.process(type.getCode(), f4, exportDto1);
        }
//        }
    }

    public void toSave() throws Exception {
        Map<String, String> reMap = new HashMap<String, String>();
        try {
            Map<String, String[]> map = request.getParameterMap();
            if (map == null || map.isEmpty()) {
                System.out.println("没有请求参数");
                return;
            }
            String[] mapStr = map.get("data");
            if (mapStr.length > 0) {
                String data = mapStr[0];
                autoSave(data);
            } else {
                System.out.println("没有请求参数");
                return;
            }


            response.setContentType("application/json");
            response.setStatus(200);
            reMap.put("result", "success");
            response.getWriter().write(JacksonMapper.bean2Json(reMap));
        } catch (Exception e) {
            e.printStackTrace();
            reMap.put("result", "failed");
            response.setContentType("application/json");
            response.setStatus(500);
            response.getWriter().write(JacksonMapper.bean2Json(reMap));
        }

    }

    private String readResultCode(String key, String val) {
        try {
            List<Result> listResult = AnalysisCache.ResultCache.get(key);
            for (Result result : listResult) {
                if (result.getResultName().equals(val)) {
                    return result.getResultCode();
                }
            }
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return "";
    }

    private String parMapVal(Map<String, String[]> map, String key) {
        String[] strArr = map.get(key);
        if (strArr != null && strArr.length > 0) {
            return strArr[0];
        }
        return null;
    }

    /**
     * 保存原始数据
     *
     * @param basePath
     * @param path
     */
    private void saveDataRaw(String basePath, String path) {
        Map map;
        File file = new File(path + "dataRaw.csv");
        if (!file.exists()) {
            File file1 = new File(basePath + "data_raw.json");
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file1)));
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
                bufferedWriter.write("fix,lefteye,raw,righteye,avg,state,time,timestamp");
                bufferedWriter.write(CommonConstants.ExportConstants.EXPORT_NEW_LINE_SIGN);
                String line = null;
                while ((line = bufferedReader.readLine()) != null) {
                    map = (Map) JacksonMapper.json2Bean(line, Map.class);
                    String temp = map.get("fix").toString() + "," + map.get("lefteye").toString().replace(",", " ")
                            + "," + map.get("raw").toString().replace(",", " ") + "," + map.get("righteye").toString().replace(",", " ")
                            + "," + map.get("avg").toString().replace(",", " ") + "," + map.get("state") + "," + " " + map.get("time")
                            + "," + " " + map.get("timestamp");
                    bufferedWriter.write(temp);
                    bufferedWriter.write(CommonConstants.ExportConstants.EXPORT_NEW_LINE_SIGN);
                }
                bufferedReader.close();
                bufferedWriter.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private boolean saveImage(String imageStr, String fileName) {
        if (StringUtils.isBlank(imageStr)) {
            return false;
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(fileName);
            imageStr = imageStr.substring(imageStr.indexOf(",") + 1);
            byte[] b = BASE64.decode(imageStr);
            for (int i = 0; i < b.length; ++i) {
                // 调整异常数据
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            fos.write(b);
            fos.flush();
            fos.close();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    public String getProjectCode() {
        return projectCode;
    }

    public void setProjectCode(String projectCode) {
        this.projectCode = projectCode;
    }

    public String getSchemeCode() {
        return schemeCode;
    }

    public void setSchemeCode(String schemeCode) {
        this.schemeCode = schemeCode;
    }

    public String getMaterialCode() {
        return materialCode;
    }

    public void setMaterialCode(String materialCode) {
        this.materialCode = materialCode;
    }

    public String getMaterialSuffix() {
        return materialSuffix;
    }

    public void setMaterialSuffix(String materialSuffix) {
        this.materialSuffix = materialSuffix;
    }
}
